package com.mindprod.example;

import java.awt.Color;
import java.util.Comparator;

/**
 * objects we will sort, represent animals, not nested
 */
public class Animal implements Comparable<Animal>
    {
    // ------------------------------ FIELDS ------------------------------

    /**
     * what color this animal is.
     */
    final Color color;

    /**
     * name of the animal
     */
    final String name;

    /**
     * how many legs this animal has
     */
    final int legs;

    // -------------------------- PUBLIC INSTANCE  METHODS --------------------------
    /**
     * Sort by elaspedTime, fastest first.
     * Defines default the sort order for Animal Objects.
     * Compare this Animal with another Animal.
     * Compares legs then color.getRGB() & 0xffffff.
     * Informally, returns (this-other) or +ve if this is more positive than other.
     *
     * @param other other Animal to compare with this one
     *
     * @return +ve if this&gt;other, 0 if this==other, -ve if this&lt;other
     */
    public final int compareTo( Animal other )
        {
        int diff = this.legs - other.legs;
        if ( diff != 0 )
            {
            return diff;
            }
        return ( this.color.getRGB() & 0xffffff ) - ( other.color.getRGB() & 0xffffff );
        }

    /**
     * what colour is the animal
     *
     * @return colour
     */
    public Color getColor()
        {
        return color;
        }

    /**
     * how many legs has this animal?
     *
     * @return number of legs
     */
    public int getLegs()
        {
        return legs;
        }

    /**
     * override usual ToString to give a debugging representation.
     *
     * @return name, color, legs as a string.
     */
    public String toString()
        {
        return name + "  " + color + " " + legs;
        }

    // --------------------------- CONSTRUCTORS ---------------------------

    /**
     * constructor
     *
     * @param name  name of the animal.
     * @param color what colonr the animal is
     * @param legs  howw many legs the animal has
     */
    Animal( String name, Color color, int legs )
        {
        this.name = name;
        this.color = color;
        this.legs = legs;
        }

    // -------------------------- INNER CLASSES --------------------------

    /**
     * Describe/summarise the comparison here..
     *
     * @author ...
     * @version 1.0 2009-04-28 - initial release
     * @since 2009-04-28
     */
    static class Alphabetically implements Comparator<Animal>
        {
        // -------------------------- PUBLIC INSTANCE  METHODS --------------------------
        /**
         * Describe/summarise the comparison here..
         * Defines an alternate sort order for Animal.
         * Compare two Animal Objects.
         * Compares name.
         * Informally, returns (a-b), or +ve if a is more positive than b.
         *
         * @param a first Animal to compare
         * @param b second Animal to compare
         *
         * @return +ve if a&gt;b, 0 if a==b, -ve if a&lt;b
         */
        public final int compare( Animal a, Animal b )
            {
            return a.name.compareToIgnoreCase( b.name );
            }
        }

    /**
     * Comparator for sorting Animals by Color then legs
     */
    static class ByRGB implements Comparator<Animal>
        {
        // -------------------------- PUBLIC INSTANCE  METHODS --------------------------
        /**
         * compare two animal objects
         *
         * @param o1 first object
         * @param o2 second object
         *
         * @return +ve if o1 is biggern, -ve if smaller, 0 if equal
         */
        public int compare( Animal o1, Animal o2 )
            {
            int diff = ( o1.color.getRGB() & 0xffffff ) - ( o2.color.getRGB() & 0xffffff );
            if ( diff != 0 )
                {
                return diff;
                }
            return o1.legs - o2.legs;
            }
        }
    }
